/*
 * TelnetInterface.java
 *
 * Created on Mar 4, 2010, 5:43:05 PM
 */

package TelnetClient;

import FICS.ChallengeDialog;
import FICS.GameOverDialog;
import FICS.SimpleFICSInterface;
import TelnetClient.dependencies.TelnetProtocolHandler;
import TelnetClient.dependencies.TelnetWrapper;
import bbchess.GameManager;
import bbchess.MainGui;
import bbchess.units.ChessBoard;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.ArrayList;

/**
 *
 * @author Tyler
 */
public class TelnetInterface extends javax.swing.JDialog {

    // initialize variables
    MainGui gui;
    ChessBoard board;
    private Process p;
    private String move;
    private TelnetWrapper telnet;
    private TelnetProtocolHandler handler;
    private boolean running;
    private GameManager gameManager;
    private Thread reader;
    private String username;
    private String password;
    private SimpleFICSInterface ficsInterface;
    private boolean parsingPlayers;
    private boolean parsingGames;
    private boolean parsingSought;

    private ArrayList<String> playerNames;

    /** Creates new form EngineInterface */
    public TelnetInterface(java.awt.Frame parent, boolean modal, String username, String password) {
        super(parent, modal);
        initComponents();
        this.setLocationRelativeTo(null);
        inputField.requestFocus();
        this.username = username;
        this.password = password;
        gui = (MainGui) parent;
        board = gui.getChessBoard();
        gameManager = gui.gameManager;
        telnet = new TelnetWrapper();
        running = false;

        parsingPlayers = false;
        parsingGames = false;
        parsingSought = false;

        playerNames = new ArrayList<String>();

        startTelnet();
    }

    @Override
    public void hide() {
        ficsInterface.setConsoleMenuItemSelected(false);
        super.hide();
    }

    //public void setFicsInterface(FICSInterface ficsInterface) {
    public void setFicsInterface(SimpleFICSInterface ficsInterface) {
        this.ficsInterface = ficsInterface;
    }

    public SimpleFICSInterface getFicsInterface() {
        return ficsInterface;
    }

    @Override
    public void setVisible(boolean b) {
        // if dialog is set to visible, transfer focus back to inputField
        if (b) {
            if (!inputField.hasFocus()) {
                inputField.requestFocus();
            }
        }

        super.setVisible(b);
    }

    private void send() {
        String inText = inputField.getText();
        inputField.setText("");
        tellTelnet(inText);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        inputField = new javax.swing.JTextField();
        sendButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        telnetTextArea = new javax.swing.JTextArea();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        lastMoveLabel = new javax.swing.JLabel();
        lastMove = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        whitePlayerLabel = new javax.swing.JLabel();
        blackPlayerLabel = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        myNameLabel = new javax.swing.JLabel();
        jMenuBar1 = new javax.swing.JMenuBar();
        telnetMenu = new javax.swing.JMenu();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        startTelnetMenuItem = new javax.swing.JMenuItem();
        stopTelnetMenuItem = new javax.swing.JMenuItem();

        setTitle("Free Internet Chess Server");

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Free Internet Chess Server"));

        inputField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                inputFieldKeyPressed(evt);
            }
        });

        sendButton.setText("Send");
        sendButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sendButtonActionPerformed(evt);
            }
        });

        jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        jScrollPane1.setAutoscrolls(true);

        telnetTextArea.setBackground(new java.awt.Color(0, 0, 0));
        telnetTextArea.setColumns(20);
        telnetTextArea.setEditable(false);
        telnetTextArea.setForeground(new java.awt.Color(51, 204, 0));
        telnetTextArea.setRows(5);
        jScrollPane1.setViewportView(telnetTextArea);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addComponent(inputField, javax.swing.GroupLayout.DEFAULT_SIZE, 338, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(sendButton))
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 189, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(inputField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(sendButton)))
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Information"));

        jLabel1.setText("Last Move: ");

        lastMove.setText("...");

        jLabel2.setText("White Player:");

        jLabel3.setText("Black Player:");

        whitePlayerLabel.setText("...");

        blackPlayerLabel.setText("...");

        jLabel4.setText("My Name:");

        myNameLabel.setText("...");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3))
                        .addGap(18, 18, 18)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(myNameLabel)
                            .addComponent(lastMove)
                            .addComponent(whitePlayerLabel)
                            .addComponent(blackPlayerLabel)))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(74, 74, 74)
                        .addComponent(lastMoveLabel))
                    .addComponent(jLabel4))
                .addContainerGap(306, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(myNameLabel))
                .addGap(17, 17, 17)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(lastMoveLabel)
                    .addComponent(lastMove))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(whitePlayerLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(blackPlayerLabel)))
        );

        telnetMenu.setText("Telnet");
        telnetMenu.add(jSeparator1);

        startTelnetMenuItem.setText("Start Telnet");
        startTelnetMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startTelnetMenuItemActionPerformed(evt);
            }
        });
        telnetMenu.add(startTelnetMenuItem);

        stopTelnetMenuItem.setText("Stop Telnet");
        stopTelnetMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                stopTelnetMenuItemActionPerformed(evt);
            }
        });
        telnetMenu.add(stopTelnetMenuItem);

        jMenuBar1.add(telnetMenu);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendButtonActionPerformed
        send();
    }//GEN-LAST:event_sendButtonActionPerformed

    private void startTelnetMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startTelnetMenuItemActionPerformed
        startTelnet();
    }//GEN-LAST:event_startTelnetMenuItemActionPerformed

    private void stopTelnetMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_stopTelnetMenuItemActionPerformed
        stopTelnet();
    }//GEN-LAST:event_stopTelnetMenuItemActionPerformed

    private void inputFieldKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_inputFieldKeyPressed
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            send();
        }
    }//GEN-LAST:event_inputFieldKeyPressed

    /**
     * Start and connect to telnet
     * @return
     */
    public void startTelnet() {

        try {
            gameManager.getPvpdialog().updateStatusLabel("Connecting...");
            telnet.connect("freechess.org", 5000);
        } catch (Exception ex) {
            appendText("Cannot connect to FICS");
            gameManager.getPvpdialog().updateStatusLabel("Cannot connect to FICS.");
            gameManager.getPvpdialog().setLoginButtonsEnabled(true);
        }

        // TODO: Update pvpdialog status to connected
        
        telnetTextArea.setText(telnet.getPrompt());
        handler = telnet.getHandler();
        start();

        appendText("Connected to FICS");
        gameManager.getPvpdialog().updateStatusLabel("Initializing");
    }

    public void stopTelnet() {
        stop();
        tellTelnet("quit");
    }

    public void waitForNextMove(int depth) {
        String depthString = String.valueOf(depth);
        tellTelnet("go depth " + depthString);

        // TODO tell engine how much time is left on the clock
    }

    public void tellTelnet(String inText) {
        try {
            telnet.send(inText);
        } catch (Exception ex) {appendText("Error sending: " + inText);}
    }

    private void setMove(String move) {
        if (move != null) {
            this.move = move.trim();
            try {
                board.getMove(move);
            } catch (Exception ex) {  }
        }
    }

    private String getMove() {
        return move;
    }

    public void appendText(String inText) {
        if (inText != null) {
            telnetTextArea.append(inText);
            parse(inText);
            jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum());
        }
    }

    /**
     * Called by parse() to parse the incoming text for login information,
     * and process it accordingly.
     * @param inText
     */
    private void parseLogin(String inText) {
        // user name
        if (inText.contains("login:")) {
            if (username == null) {
                try {
                    telnet.send("guest");
                } catch (Exception ex) {
                }
            }

            else {
                try {
                    telnet.send(username);
                } catch (Exception ex) { }
            }
        }

        //password
        if (inText.contains("password:")) {
            try {
                telnet.send(password);
            } catch (Exception ex) { }
        }

        // if invalid password
        if (inText.contains("**** Invalid password! ****")) {
            gameManager.getPvpdialog().updateStatusLabel("Invalid Password!");
            gameManager.getPvpdialog().setLoginButtonsEnabled(true);
            gui.clearTelnetInterface();
            inText = "";
            dispose();
        }

        // press return (used after login)
        if (inText.contains("Press return")) {
            try {
                telnet.send(" ");
            } catch (Exception ex) {
            }
        }

        // after login, check for my name
        if (inText.contains("Starting FICS session as ")) {
            String split[] = inText.split(" ");
            String split2 = split[5];
            String split3[] = split2.split("\\(");

            String myName = split3[0];

            myNameLabel.setText(myName);
            ficsInterface.setNameLabel(myName);
            gameManager.setPlayerName(myName);

            gameManager.getPvpdialog().dispose();
            ficsInterface.setVisible(true);

            // set interface
            try {
                telnet.send("set seek 0");
                telnet.send("iset compressmove");
                telnet.send("set Interface BlackBox Chess");
            } catch (Exception ex) { }
        }
    }

    /**
     * Called by parse() to parse the incoming string for new game information,
     * and start a new game with the given parameters
     * @param inText
     */
    private void parseNewGame(String inText) {
        // if new game, get player names
        if (inText.contains("Creating:") && inText.contains(gameManager.getPlayerName())) {
            String split[] = inText.split(" ");
            int w = 0;
            int b = 0;
            for (int i = 0; i < 18; i++) {
                if (split[i].contains("Creating:")) {
                    w = i + 1;
                    b = i + 3;
                }
            }

            whitePlayerLabel.setText(split[w]);
            gameManager.setWhiteName(split[w]);
            blackPlayerLabel.setText(split[b]);
            gameManager.setBlackName(split[b]);

            gameManager.networkGameStart();
        }
    }

    /**
     * Called by parse() to determine if the incoming string contains any
     * new move information.
     * @param inText
     */
    private void parseMove(String inText) {
        if (inText.contains("<d1>")) {
            String split[] = inText.split(" ");
            String newMove = split[4].substring(0, 4);

            // promoted?
            String promo = "";
            try {
                if (split[4].length() == 5) {
                    promo = split[4].substring(4, 5);
                } else {
                    promo = split[4].substring(5, 6);
                }
            } catch (Exception ex) {
            }

            // if captured a move to be promoted, first letter will be lower case
            if (promo.equals("B") ||
                    promo.equals("Q") ||
                    promo.equals("N") ||
                    promo.equals("R")) {
                try {
                    promo = split[4].substring(5, 6);
                } catch (Exception ex) {
                }
            }

            if (newMove != null) {
                setMove(newMove + promo);
                lastMove.setText(newMove + promo);
            }
        }
    }

    /**
     * Called by parse() to determine if the incoming string has any 'say' information.
     * @param inText
     */
    private void parseSay(String inText) {
        if (inText.contains("says:")) {

            String split[] = inText.split("\\(");
            String name = split[0];
            name = name.substring(1, name.length()).toString();

            int startOfMessage = inText.indexOf("says:") + 6;

            String message = inText.subSequence(startOfMessage, inText.length() - 7).toString();

            ficsInterface.sendToGameChat(name + ": " + message);
        }
    }

    private void parseChallenge(String inText) {
        if (inText.contains("Challenge:") && inText.contains(gameManager.getPlayerName())) {
            new ChallengeDialog(gui, true, this, inText).setVisible(true);
        }
    }

    /**
     * Parses the incoming player list. Only parses information if parsingPlayers
     * is true. Sets parsingPlayers to false after list has been read.
     * @param inText
     */
    private void parsePlayers(String inText) {
        if (parsingPlayers) {

            boolean lastParse = false;

            if (inText.contains("fics%")) {
                lastParse = true;
                //inText = inText.substring(0, inText.length()-55);
                //inText = "";
            }

            boolean newRating = false;
            boolean beginParen = false;
            //System.out.println(inText);

            String[] playersArray1 = inText.split("  ");

            // remove white spaces
            for (String p : playersArray1) {

                if (lastParse == true) {
                    int length = getPlayerNames().size();

                    // remove fics% prompt and information
                    // after names are listed
                    //if (p.contains("fics%")) {
                        //p = "";
                    //}
                }

                char playerName[] = p.toCharArray();
                String newPlayerName = "";

                for (char i : playerName) {
                    // don't add these char's!
                    if (i == '\n') {
                        //
                    } // else if theres rating info

                    // start of parenthesis
                    else if (i == '(') {
                        beginParen = true;
                    }

                    // if we're inside of parenthesis, all text gets filtered through here
                    else if (beginParen) {
                        
                        // i is either going to be a variable or an end paren

                        if (i == ')') {
                            beginParen = false;
                        }
                    }

                    else if (i == '+'
                            || i == '-'
                            || i == ' '
                            || i == '.'
                            || i == '1'
                            || i == '2'
                            || i == '3'
                            || i == '4'
                            || i == '5'
                            || i == '6'
                            || i == '7'
                            || i == '8'
                            || i == '9'
                            || i == '0') {

                        if (i == ' '
                                || i == '.') {
                            if (!newRating) {
                                System.out.print(", ");
                                newRating = true;
                            }
                        } else {
                            newRating = false;
                            // print rating
                            //System.out.print(i);
                        }
                    } else {
                        // if a new line, make a new name
                        if (i == '\r') {
                            getPlayerNames().add(newPlayerName);
                            newPlayerName = "";
                        } // else add the name
                        else {
                            newPlayerName = newPlayerName.concat("" + i);
                        }
                    }
                }

                if (newPlayerName.length() > 1) {
                    getPlayerNames().add(newPlayerName);
                }
            }


            if (lastParse == true) {
                parsingPlayers = false;

                // remove last 3 playerNames since they are just
                // fics% and labels
                getPlayerNames().remove(getPlayerNames().size()-1);
                getPlayerNames().remove(getPlayerNames().size()-1);
                getPlayerNames().remove(getPlayerNames().size()-1);

                ficsInterface.setPlayerList(getPlayerNames());

                playerNames.clear();
            }

            inText = "";
        }
    }

    /**
     * Parses the incoming games list. Only parses information if parsingGames
     * is true. Sets parsingGames to false after list has been read.
     * @param inText
     */
    private void parseGames(String inText) {
        if (parsingGames) {
            ficsInterface.updateGameList(inText);

            if (inText.contains("fics%")) {
                parsingGames = false;
            }

            inText = "";
        }
    }

    /**
     * Parses the incoming sought games list. Only parses information if parsingSough
     * is true. Sets parsingSought to false after list has been read.
     * @param inText
     */
    private void parseSought(String inText) {
        if (parsingSought) {

            ficsInterface.updateSoughtList(inText);

            if (inText.contains("fics%")) {
                parsingSought = false;
            }

            inText = "";
        }
    }

    /**
     * Parse inText for abort tag
     * @param inText
     */
    private void parseAbort(String inText) {
        if (gameManager.isPlayingOnline()) {
            if (inText.contains("Game aborted") && inText.contains(gameManager.getWhiteName()) && inText.contains(gameManager.getBlackName())) {
                gameManager.endGame();
                GameOverDialog gameOverDialog = new GameOverDialog(gui, true, this, "Game aborted by player.");
                gameOverDialog.setVisible(true);
            }
        }
    }

    private void parseDisconnect(String inText) {
        if (gameManager.isPlayingOnline()) {
            if (inText.contains("forfeits by disconnection}") && inText.contains(gameManager.getWhiteName()) && inText.contains(gameManager.getBlackName())) {
                GameOverDialog gameOverDialog = new GameOverDialog(gui, true, this, "Opponent disconnected.");
                gameOverDialog.setVisible(true);
                gameManager.endGame();
            }
        }
    }

    /**
     * Sets parsingPlayers to true, thereby enabling parsePlayers() to parse
     * incoming player information.
     */
    public void updatePlayers() {

        if (parsingPlayers == false
                && parsingGames == false
                && parsingSought == false) {

            tellTelnet("players");
            parsingPlayers = true;

        }
    }

    public void updateGames() {

        if (parsingPlayers == false
                && parsingGames == false
                && parsingSought == false) {

            tellTelnet("games");
            ficsInterface.clearGameList();
            parsingGames = true;
            
        }
    }

    public void updateSought() {

        if (parsingPlayers == false
                && parsingGames == false
                && parsingSought == false) {

            tellTelnet("sought");
            ficsInterface.clearSoughtList();
            parsingSought = true;

        }
    }

    // Parse the incoming text
    public void parse(String inText) {

        // parse players (clears inText if players are to be parsed)
        parsePlayers(inText);

        // parse games (clears inText if players are to be parsed)
        parseGames(inText);

        // parse sought (clears inText if players are to be parsed)
        parseSought(inText);

        // if login
        parseLogin(inText);
        
        // if new game
        parseNewGame(inText);
        
        // if move
        parseMove(inText);

        // if 'say' command
        parseSay(inText);

        // if challenge
        parseChallenge(inText);

        // if game aborted
        parseAbort(inText);

        // if opponent disconnects
        parseDisconnect(inText);
    }

    /**
     * Start telnet
     */
    public void start()
    {
	try
	{
	    reader = new Thread(new TelnetReader());
	    running = true;
	    reader.start();
	}
	catch (Exception e)
	{
	    appendText("Error connecting to telnet");
	    stop();
	}
    }

    /**
     * Stop telnet
     */
    public void stop() {
        try {
            telnet.disconnect();
            running = false;
        } catch (Exception e) {
            // ignore
        }
        reader = null;
    }

    /**
     * @return the playerNames
     */
    public ArrayList<String> getPlayerNames() {
        return playerNames;
    }

    class TelnetReader implements Runnable {

        /**
         * Continuously read from remote host and display the data on screen.
         */
        public void run() {
            byte[] b = new byte[256];
            int n = 0;
            while (running && n >= 0) {
                try {
                    do {
                        n = handler.negotiate(b);
                        if (n > 0) {
                            appendText(new String(b, 0, n));
                        }
                    } while (running && n > 0);
                    n = telnet.read(b);
                    handler.inputfeed(b, n);
                } catch (IOException e) {
                    stop();
                    break;
                }
            }
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel blackPlayerLabel;
    private javax.swing.JTextField inputField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JLabel lastMove;
    private javax.swing.JLabel lastMoveLabel;
    private javax.swing.JLabel myNameLabel;
    private javax.swing.JButton sendButton;
    private javax.swing.JMenuItem startTelnetMenuItem;
    private javax.swing.JMenuItem stopTelnetMenuItem;
    private javax.swing.JMenu telnetMenu;
    private javax.swing.JTextArea telnetTextArea;
    private javax.swing.JLabel whitePlayerLabel;
    // End of variables declaration//GEN-END:variables

}
